/*
Copyright (c) 2011, Dmitry S. Kuznetsov <zendipy@gmail.com>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

   - Redistributions of source code must retain the above copyright notice,
     this list of conditions and the following disclaimer.
   - Redistributions in binary form must reproduce the above copyright notice,
     this list of conditions and the following disclaimer in the documentation and/or
     other materials provided with the distribution.
   - Neither the name of the copyright holde nor the names of its contributors
     may be used to endorse or promote products derived from this software
     without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY Dmitry S. Kuznetsov AS IS AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGE.
*/

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTextCodec>
#include "alglib/linalg.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    criteriaModel = new QStandardItemModel();
    alternativeModel = new QStandardItemModel();
    this->ui->criteriaListView->setModel(criteriaModel);
    this->ui->alternativesListView->setModel(alternativeModel);
    ui->saveHierarchyButton->setEnabled(false);
    ui->helpLabel->setText("1 - equal importance         7 - a very significant superiority\n3 - moderate superiority     9 - overwhelming superiority\n5 - significant superiority  2,4,6,8 - intermediate values (for the compromise situations)");


}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actionNew_problem_activated()
{
   ui->nameEdit->clear();
   criteriaModel->clear();
   alternativeModel->clear();
   ph = NULL;
}

// save hierarchy
void MainWindow::on_saveHierarchyButton_clicked()
{
    ph = new ProblemHierarchy(this);
    ph->setName(ui->nameEdit->text());
    int i = 0;
    while(criteriaModel->item(i,0) != 0)
    {
        ph->addCriterion(criteriaModel->item(i,0)->text());
        i++;
    }

    i = 0;
    while(alternativeModel->item(i,0) != 0)
    {
        ph->addAlternative(alternativeModel->item(i,0)->text());
        i++;
    }

    ui->saveHierarchyButton->setEnabled(false);

    createMatrix2();

}


// add new criterion
void MainWindow::on_addCriterionButton_clicked()
{
    QStandardItem *parentItem = criteriaModel->invisibleRootItem();

    QStandardItem *item = new QStandardItem("New criterion");
    parentItem->appendRow(item);
    ui->saveHierarchyButton->setEnabled(true);
}

// delete criterion
void MainWindow::on_delCriterionButton_clicked()
{
    this->criteriaModel->removeRow(this->critSelectedItemIndex.row());
    //ph->delCriterion(this->critSelectedItemIndex.row());
    ui->saveHierarchyButton->setEnabled(true);
}


// add new alternative
void MainWindow::on_addAlternativeButton_clicked()
{
    QStandardItem *parentItem = alternativeModel->invisibleRootItem();

    QStandardItem *item = new QStandardItem("New alternative");
    parentItem->appendRow(item);
    ui->saveHierarchyButton->setEnabled(true);
}

// delete alternative
void MainWindow::on_deleteAlternativeButton_clicked()
{
    this->alternativeModel->removeRow(this->alterSelectedItemIndex.row());
    //ph->delAlternative(this->alterSelectedItemIndex.row());
    ui->saveHierarchyButton->setEnabled(true);
}

// on criteria list click
void MainWindow::on_criteriaListView_clicked(const QModelIndex &index)
{
    this->critSelectedItemIndex = index;
}

// on alternatoves list click
void MainWindow::on_alternativesListView_clicked(const QModelIndex &index)
{
    this->alterSelectedItemIndex = index;
}

/** fill tableWibget for matrix of pairwise
  comparation fo 2nd lvl of hierarchy
  */
void MainWindow::createMatrix2()
{
    /** main matrix */
    ui->matrix2TableWidget->setRowCount(ph->getCriteriaQuantity());
    ui->matrix2TableWidget->setColumnCount(ph->getCriteriaQuantity());
    ui->matrix2TableWidget->setHorizontalHeaderLabels(ph->getCriteria());
    ui->matrix2TableWidget->setVerticalHeaderLabels(ph->getCriteria());
    //QTableWidgetItem *newItem = new QTableWidgetItem(tr("Ntaaa"));
    //ui->matrix2TableWidget->setItem(0, 0, newItem);
    // fil diagonal
    for(int i = 0; i < ph->getCriteriaQuantity(); i++)
    {
        QTableWidgetItem *newItem = new QTableWidgetItem(tr("1"));
        newItem->setBackgroundColor(Qt::gray);
        ui->matrix2TableWidget->setItem(i, i, newItem);
    }

    /** matrix with vector of priorities */
    QList<QString> *hHeaders = new QList<QString>();
    hHeaders->append("The vector of\npriorities");

    ui->vectorTableWidget->setColumnCount(1);
    ui->vectorTableWidget->setRowCount(ph->getCriteriaQuantity());
    ui->vectorTableWidget->setHorizontalHeaderLabels(*hHeaders);
}

// if user change data into the cell
void MainWindow::on_matrix2TableWidget_cellChanged(int row, int column)
{
    // not for diagonal cells
    if(row != column)
    {
        if(ui->matrix2TableWidget->item(row,column)->text() != "")
        {
            bool convertOk;
            double curCell = ui->matrix2TableWidget->item(row,column)->text().toDouble(&convertOk);
            // if user inputs a number
            if(convertOk){
                double relCell = 1/ curCell;
                QTableWidgetItem *newItem = new QTableWidgetItem(QString::number(relCell));
                newItem->setBackgroundColor(Qt::gray);
                ui->matrix2TableWidget->blockSignals(true);
                ui->matrix2TableWidget->setItem(column, row, newItem);
                ui->matrix2TableWidget->blockSignals(false);
            }
            /* if user inputs any but number
              clear currecn cell and show message
             */
            else
            {
                // clear current cell
                ui->matrix2TableWidget->blockSignals(true);
                ui->matrix2TableWidget->item(row,column)->setText("");
                ui->matrix2TableWidget->blockSignals(false);
                //TODO show message
            }
        }
    }
}

/** make calculation for matrix of pairwise
  comparation fo 2nd lvl of hierarchy
   lambda_max - maximum eigenvalue
  */
void MainWindow::on_calcMatrix2Button_clicked()
{
    /** maximum eigenvalue */
    int matrixSize = ph->getCriteriaQuantity();
    alglib::real_1d_array lambdav;
    alglib_impl::ae_matrix *p = new alglib_impl::ae_matrix();
    lambdav.setlength(matrixSize);
    alglib::real_2d_array matrix = new alglib::real_2d_array(p);
    matrix.setlength(matrixSize,matrixSize);
    // compile matrix (MUST start with 0 index!!!)


    for(int i = 0; i < matrixSize; i++){
        for(int j = 0; j < matrixSize; j++){
            matrix[i][j] = ui->matrix2TableWidget->itemAt(i,j)->text().toDouble();
        }
    }
    // get eigenvalue
    //!hmatrixevd(al, n, 0, ae_false, &lambdav, &z, _state) )
    alglib::hmatrixevd(matrix, matrixSize, 0, ae_false, &lambdav,NULL);

}
